import os
import re
import shutil
from urllib.parse import urlencode, quote

import pandas as pd
import requests
import urllib3
import datetime

from base.util.common_util import get_project_root
from base.util.file_util import check_path


def write_EDL_file(ip):
    with open("statistic_file.txt", 'a+') as filename:
        filename.write(ip + "\r\n")
        filename.close()
    with open("edl_deny_ip_waf.txt", 'a+') as filename:
        filename.write(ip + "\r\n")
        filename.close()
        print('{datetimes} 永久阻止Ip地址 {ips}'.format(datetimes=datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
                                                        ips=ip))
        return [0, ip]


def req(method, url, body=None, headers=None, cookies=None, params=None):
    if params is None:
        params = {}
    if cookies is None:
        cookies = {}
    if headers is None:
        headers = {}
    if body is None:
        body = {}
    result = requests.request(method, url, params=params, data=body, headers=headers, cookies=cookies, verify=False)
    return result


def get_cookie():
    cookies_list = eval(req('POST', 'https://10.88.88.115:8083/SecureSphere/api/v1/auth/session',
                            {}, {'Authorization': 'Basic c2VjYWRtaW46SHIxeWNmbEAxMzg='}).text).get('session-id').split(
        ';')[0].split('=')
    return {'JSESSIONID': cookies_list[1]}


def get_all_group_server(sites_list, cookies):
    all_groupServer_dict = {}
    for i in sites_list:
        groupServer_Name = req('GET', f'https://10.88.88.115:8083/SecureSphere/api/v1/conf/serverGroups/{i}', body={},
                               headers={}, cookies=cookies).text
        groupServer_Name = eval(groupServer_Name)
        all_groupServer_dict[i] = groupServer_Name.get('server-groups')
    return all_groupServer_dict


def group_by_active_or_simulation(all_groupServer_dict, cookies):
    active_Server = {}
    for site_name in all_groupServer_dict.keys():
        for group_name in all_groupServer_dict.get(site_name):
            si = eval(req('GET',
                          f'https://10.88.88.115:8083/SecureSphere/api/v1/conf/serverGroups/{site_name}/{group_name}',
                          body={}, headers={}, cookies=cookies).text)
            if si.get('operationMode') == 'active':
                active_Server[si.get('name')] = site_name
    return active_Server


def get_violations(cookies: dict, last_few_days: int, site_name: str,
                   server_group_name: str, limit: int):
    return eval(req('GET', 'https://10.88.88.115:8083/SecureSphere/api/v1/monitor/violations/',
                    cookies=cookies, params=urlencode(
            {'siteName': site_name,
             'serverGroupName': server_group_name,
             'limit': limit,
             'lastFewDays': last_few_days},
            quote_via=quote)).text).get('violations')


def get_active_group(cookies):
    active_server = group_by_active_or_simulation(get_all_group_server(
        eval(req('GET', 'https://10.88.88.115:8083/SecureSphere/api/v1/conf/sites', body={}, cookies=cookies).text).get(
            'sites'), cookies), cookies)
    try:
        active_server.pop('测试影像')
    except BaseException as e:
        print(e)
    return active_server


def extract_time_from_filename(filename: str):
    match = re.search(r'threat_db_(.*)\.csv', filename)
    if match:
        return match.group(1)
    return None


def get_dangerous_from_imperva(start_time, end_time, get_new: bool = False):
    urllib3.disable_warnings()
    start = datetime.datetime.now()
    tmp_path = check_path(f"{get_project_root()}tmp{os.sep}")
    if get_new:
        pass
    else:
        path_list = [path for path in os.listdir(tmp_path) if ".csv" in path]
        if len(path_list) == 1:
            path = path_list[0]
            time_str = extract_time_from_filename(path)
            if time_str:
                file_time = datetime.datetime.strptime(time_str, "%Y_%m_%d_%H_%M_%S")
                if abs(file_time - start).days <= 1:
                    res_df = pd.read_csv(f"{tmp_path}{path}")
                    res_df['THREAT_TIME']=pd.to_datetime(res_df['THREAT_TIME'])
                    filters = res_df[(res_df['THREAT_TIME'] >= start_time) & (res_df['THREAT_TIME'] <= end_time)]
                    return filters
    shutil.rmtree(tmp_path)
    cookies = get_cookie()
    res_df = pd.DataFrame()
    group = get_active_group(cookies)
    for index, (server_group_name, site_name) in enumerate(group.items()):
        print(f"开始获取{index + 1}/{len(group)}:{server_group_name}-{site_name}")
        violations_events = get_violations(cookies=cookies,
                                           site_name=site_name,
                                           server_group_name=server_group_name,
                                           limit=4000,
                                           last_few_days=30)
        res_df = pd.concat([res_df, pd.DataFrame(violations_events)], ignore_index=True)
    res_df['THREAT_TIME'] = pd.to_datetime(res_df['time'], format='%a %b %d %H:%M:%S CST %Y')
    res_df.drop(['time'], axis=1, inplace=True)
    res_df.rename(columns={
        "sourceIp": "SIP",
        "sourcePort": "S_PORT",
        "destIp": "DIP",
        "destPort": "D_PORT",
        "severity": "SEVERITY",
        "description": "THREAT_SUMMARY",
        "action": "DENY_METHOD"
    }, inplace=True)
    res_df['PROTOCOL'] = ""
    end_time = datetime.datetime.now()
    print(f"获取完毕，共计：{len(res_df)}｜耗时:{end_time - start}")
    res_df.to_csv(f"{check_path(tmp_path)}threat_db_{end_time.strftime('%Y_%m_%d_%H_%M_%S')}.csv",
                  index=False, errors="replace")
    filters = res_df[(res_df['THREAT_TIME'] >= start_time) & (res_df['THREAT_TIME'] <= end_time)]
    return filters


# if __name__ == '__main__':
    # config_yaml, config_file = get_config()
    # start_time = config_yaml['session']['start_time']
    # end_time = config_yaml['session']['end_time']
    # res = get_dangerous_from_imperva(start_time, end_time, get_new=True)
    # res.to_csv("a.csv", index=False)
    # print(len(res))
